/* eslint-disable @typescript-eslint/explicit-function-return-type */
import { useState, useEffect, useCallback, useMemo, useRef } from 'react'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Progress } from '@/components/ui/progress'
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'
import FileSelector from '@/components/ui/FileSelector'
import { useConfig } from '@/context/config-context'
import { toast } from 'sonner'

// 处理状态类型
type ProcessStateType = 'IDLE' | 'RUNNING' | 'EXITED' | 'CRASHED'

const ElevationGridSlicer = () => {
  const { config, updateConfig, saveConfig } = useConfig()
  const [geojsonPath, setGeojsonPath] = useState<string | null>(null)
  const [tifPath, setTifPath] = useState<string | null>(null)
  const [outputDir, setOutputDir] = useState<string | null>(null)
  const [isLoading, setIsLoading] = useState(false)

  // 添加切片类型状态
  const [sliceType, setSliceType] = useState<number>(0)

  // 添加目标坐标系状态
  const [targetEpsg, setTargetEpsg] = useState<number>(3857)

  // 进度相关状态
  const [processProgress, setProcessProgress] = useState<string>('准备处理')
  const [processPercent, setProcessPercent] = useState<number>(0)
  const [showProgress, setShowProgress] = useState(false)

  // 模拟进度相关
  const [isSimulating, setIsSimulating] = useState(false)
  const simulationIntervalRef = useRef<number | null>(null)
  const lastRealProgressRef = useRef<number>(0)

  // 网格参数
  const [gridParams, setGridParams] = useState({
    size: 5000,
    pixel_size: 5
  })

  // 高度参数
  const [heightParams, setHeightParams] = useState({
    minheight: 30,
    maxheight: 40,
    step: 10,
    increment: 10
  })

  // 添加高度配置状态
  const [altitudeParams, setAltitudeParams] = useState({
    layerField: '',
    height: 3.5,
    base_height: 0,
    elev_mode: 'max' // 默认使用包围盒最高点
  })

  // 模拟进度函数
  const startProgressSimulation = useCallback(() => {
    if (simulationIntervalRef.current) {
      window.clearInterval(simulationIntervalRef.current)
    }

    setIsSimulating(true)
    lastRealProgressRef.current = 0

    // 重置进度为初始值
    setProcessPercent(1)

    // 创建模拟进度更新间隔
    simulationIntervalRef.current = window.setInterval(() => {
      setProcessPercent((prev) => {
        // 确保模拟进度不会超过95%且不会超过实际进度
        const realProgress = lastRealProgressRef.current

        if (realProgress > 0) {
          // 如果有实际进度，模拟值不应超过实际值
          return realProgress
        }

        if (prev >= 95) {
          return prev // 保持在95%
        }

        // 根据当前进度阶段动态调整增量速率
        let increment = 0
        if (prev < 30) {
          // 初始阶段快速增长
          increment = Math.random() * 1.5 + 0.5
        } else if (prev < 60) {
          // 中间阶段中等速度增长
          increment = Math.random() * 1 + 0.3
        } else if (prev < 85) {
          // 后期缓慢增长
          increment = Math.random() * 0.5 + 0.1
        } else {
          // 接近95%时非常缓慢
          increment = Math.random() * 0.2 + 0.05
        }

        return Math.min(95, prev + increment)
      })
    }, 1000) // 每500毫秒更新一次模拟进度
  }, [])

  // 停止模拟进度
  const stopProgressSimulation = useCallback(() => {
    if (simulationIntervalRef.current) {
      window.clearInterval(simulationIntervalRef.current)
      simulationIntervalRef.current = null
    }
    setIsSimulating(false)
  }, [])

  // 处理过程状态变化
  const handleProcessStateChange = useCallback(
    (_event, state: ProcessStateType) => {
      switch (state) {
        case 'IDLE':
          setProcessProgress('准备处理')
          setIsLoading(false)
          setProcessPercent(0)
          setShowProgress(false)
          stopProgressSimulation()
          break
        case 'RUNNING':
          setProcessProgress('处理中...')
          setIsLoading(true)
          setShowProgress(true)
          startProgressSimulation()
          break
        case 'EXITED':
          setProcessProgress('处理完成')
          setIsLoading(false)
          stopProgressSimulation()
          setProcessPercent(99.99)

          // 显示完成状态2秒后隐藏进度条
          setTimeout(() => {
            setShowProgress(false)
            setProcessPercent(0)
          }, 2000)

          toast.success('网格切片生成成功')
          break
        case 'CRASHED':
          setProcessProgress('处理失败')
          setIsLoading(false)
          stopProgressSimulation()
          setShowProgress(false)
          toast.error('生成过程中发生错误')
          break
      }
    },
    [startProgressSimulation, stopProgressSimulation]
  )

  // 处理进度更新
  const handleProcessProgress = useCallback(
    (_event, percent: number) => {
      // 记录实际进度
      lastRealProgressRef.current = percent

      // 如果收到真实进度，显示真实进度
      if (percent > 0) {
        setProcessPercent(percent)
        setProcessProgress(`处理中 ${percent}%`)

        // 如果进度接近100%，可以停止模拟
        if (percent >= 99) {
          stopProgressSimulation()
        }
      }
    },
    [stopProgressSimulation]
  )

  // 确保组件卸载时清除模拟定时器
  useEffect(() => {
    return () => {
      if (simulationIntervalRef.current) {
        window.clearInterval(simulationIntervalRef.current)
      }
    }
  }, [])

  // 事件监听设置
  useEffect(() => {
    const removeStateListener = window.electron.ipcRenderer.on(
      'process-state-changed',
      handleProcessStateChange
    )

    const removeProgressListener = window.electron.ipcRenderer.on(
      'process-progress',
      handleProcessProgress
    )

    return () => {
      removeStateListener()
      removeProgressListener()
    }
  }, [handleProcessStateChange, handleProcessProgress])

  // 从配置上下文加载初始数据
  useEffect(() => {
    if (config) {
      // 加载文件路径
      setGeojsonPath(config.input_files.dsm_geo || null)
      setTifPath(config.input_files.dem_tif || null)
      setOutputDir(config.output_dir || null)

      // 加载切片类型
      setSliceType(config.slice_output.bbox_type || 0)

      // 加载目标坐标系
      setTargetEpsg(config.slice_output.target_epsg || 3857)

      // 加载网格参数
      setGridParams({
        size: config.grid.size,
        pixel_size: config.grid.pixel_size
      })

      // 加载高度参数
      setHeightParams({
        minheight: config.height.minheight,
        maxheight: config.height.maxheight,
        step: config.height.step,
        increment: config.height.increment
      })
      // 加载矢量文件高度配置
      setAltitudeParams({
        layerField: config.altitude.layerField,
        height: config.altitude.height,
        base_height: config.altitude.base_height,
        elev_mode: config.altitude.elev_mode || 'max'
      })
    }
  }, [config])

  const handleSelectGeojsonFile = async () => {
    const path = (await window.api.SelectGeojsonFile()) as string
    console.log('Selected GeoJSON file:', path)
    setGeojsonPath(path)
  }

  const handleSelectTifFile = async () => {
    const path = (await window.api.SelectTifFile()) as string
    console.log('Selected TIF file:', path)
    setTifPath(path)
  }

  const handleSelectOutputDir = async () => {
    const path = (await window.api.SelectFolder()) as string
    console.log('Selected output directory:', path)
    setOutputDir(path)
  }

  const handleGridParamChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target
    setGridParams((prev) => ({ ...prev, [name]: Number(value) }))
  }

  const handleHeightParamChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target
    setHeightParams((prev) => ({ ...prev, [name]: Number(value) }))
  }

  const handleAltitudeParamChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target
    // 处理非数字类型的输入
    if (name === 'layerField') {
      setAltitudeParams((prev) => ({ ...prev, [name]: value }))
    } else {
      setAltitudeParams((prev) => ({ ...prev, [name]: Number(value) }))
    }
  }

  // 渲染进度指示器
  const renderProgressIndicator = useMemo(() => {
    if (!showProgress) return null

    return (
      <div className="mt-5 space-y-2">
        <div className="flex justify-between items-center text-sm">
          <span className="font-medium">{processProgress}</span>
          <span className="text-muted-foreground">{Math.round(processPercent)}%</span>
        </div>
        <Progress
          value={processPercent}
          className={`h-2 ${isSimulating && !lastRealProgressRef.current ? 'animate-pulse' : ''}`}
        />
      </div>
    )
  }, [showProgress, processProgress, processPercent, isSimulating])

  const handleGenerateSlices = async () => {
    if (!geojsonPath || !tifPath || !outputDir) {
      toast.error('请选择所有必要的输入文件和输出目录')
      return
    }

    setIsLoading(true)
    setProcessProgress('准备处理')
    setProcessPercent(0)
    setShowProgress(true)
    lastRealProgressRef.current = 0

    try {
      // 更新配置文件
      await updateConfig({
        ...config,
        output_dir: outputDir,
        input_files: {
          dsm_geo: geojsonPath || '',
          dem_tif: tifPath || ''
        },
        grid: {
          size: gridParams.size,
          pixel_size: gridParams.pixel_size
        },
        height: {
          minheight: heightParams.minheight,
          maxheight: heightParams.maxheight,
          step: heightParams.step,
          increment: heightParams.increment
        },
        slice_output: {
          ...config.slice_output,
          bbox_type: sliceType,
          target_epsg: targetEpsg
        },
        altitude: {
          layerField: altitudeParams.layerField,
          height: altitudeParams.height,
          base_height: altitudeParams.base_height,
          elev_mode: altitudeParams.elev_mode
        }
      })

      // 保存配置到文件
      await saveConfig()

      // 启动处理进程
      const result = await window.api.StartProcess('grid_slicer')

      if (!result) {
        throw new Error('启动网格切片进程失败')
      }

      console.log('Started grid generation process')
    } catch (error) {
      console.error('Slice generation failed:', error)
      setIsLoading(false)
      setProcessPercent(0)
      setShowProgress(false)
      stopProgressSimulation()
      toast.error(error instanceof Error ? error.message : '网格切片生成失败，请检查参数')
    }
  }

  return (
    <Card className="w-full">
      <CardHeader>
        <CardTitle>高程数据网格切片</CardTitle>
        <CardDescription>基于矢量高程数据和地形TIF文件生成高程数据网格切片</CardDescription>
      </CardHeader>
      <CardContent className="space-y-2">
        <div className="space-y-4">
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <FileSelector
              id="geojson-file-slicer"
              label="选择矢量文件"
              value={geojsonPath || ''}
              onChange={setGeojsonPath}
              onSelectFile={handleSelectGeojsonFile}
            />
            <FileSelector
              id="tif-file"
              label="选择高程TIF文件"
              value={tifPath || ''}
              onChange={setTifPath}
              onSelectFile={handleSelectTifFile}
            />
          </div>

          {/* 输出目录选择器 */}
          <FileSelector
            id="output-dir"
            label="选择输出目录"
            value={outputDir || ''}
            onChange={setOutputDir}
            onSelectFile={handleSelectOutputDir}
            className="space-y-0"
            placeholder="请点击选择输出文件夹"
          />

          {/* 切片类型选择 */}

          <div className="flex items-center gap-4 mb-2">
            <h4>切片范围选择:</h4>
            <RadioGroup
              value={sliceType.toString()}
              onValueChange={(value) => setSliceType(parseInt(value))}
              className="flex items-center space-x-8"
            >
              <div className="flex items-center space-x-2">
                <RadioGroupItem value="0" id="slice-type-1" />
                <Label htmlFor="slice-type-1">按矢量文件</Label>
              </div>
              <div className="flex items-center space-x-2">
                <RadioGroupItem value="1" id="slice-type-2" />
                <Label htmlFor="slice-type-2">按TIF文件</Label>
              </div>
              <div className="flex items-center space-x-2">
                <RadioGroupItem value="2" id="slice-type-3" />
                <Label htmlFor="slice-type-3">两者并集</Label>
              </div>
            </RadioGroup>
          </div>
        </div>

        {/* 网格参数设置 */}
        <h4 className="font-medium ">网格参数 (米)</h4>
        <div className="flex flex-wrap gap-4">
          <div className="flex-1 min-w-[180px]">
            <div className="flex items-center gap-3">
              <Label htmlFor="size" className="text-sm whitespace-nowrap">
                网格大小 ：
              </Label>
              <Input
                id="size"
                name="size"
                type="number"
                value={gridParams.size}
                onChange={handleGridParamChange}
                className="h-9"
              />
            </div>
          </div>
          <div className="flex-1 min-w-[180px]">
            <div className="flex items-center gap-3">
              <Label htmlFor="pixel_size" className="text-sm whitespace-nowrap">
                像素大小 ：
              </Label>
              <Input
                id="pixel_size"
                name="pixel_size"
                type="number"
                value={gridParams.pixel_size}
                onChange={handleGridParamChange}
                className="h-9"
              />
            </div>
          </div>
        </div>

        {/* 高度参数设置 */}
        <h4 className="font-medium">高度参数 (米)</h4>
        <div className="flex flex-wrap gap-2">
          {[
            { id: 'minheight', label: '最小高度' },
            { id: 'maxheight', label: '最大高度' },
            { id: 'step', label: '步长' }
            // { id: 'increment', label: '增量' }
          ].map((field) => (
            <div key={field.id} className="flex-1 min-w-[140px]">
              <div className="flex items-center gap-2">
                <Label htmlFor={field.id} className="text-sm whitespace-nowrap">
                  {field.label}：
                </Label>
                <Input
                  id={field.id}
                  name={field.id}
                  type="number"
                  value={heightParams[field.id as keyof typeof heightParams]}
                  onChange={handleHeightParamChange}
                  className="h-8"
                />
              </div>
            </div>
          ))}
        </div>

        {/* 矢量文件高度配置 */}
        <h4 className="font-medium">矢量高度参数</h4>
        <div className="flex gap-4">
          <div className="flex items-center gap-2 flex-1">
            <Label htmlFor="layerField" className="text-sm whitespace-nowrap">
              层高字段：
            </Label>
            <Input
              id="layerField"
              name="layerField"
              value={altitudeParams.layerField}
              onChange={handleAltitudeParamChange}
              placeholder="输入层高字段名称"
              className="h-9"
            />
          </div>
          <div className="flex items-center gap-2 flex-1">
            <Label htmlFor="height" className="text-sm whitespace-nowrap">
              层高 (米)：
            </Label>
            <Input
              id="height"
              name="height"
              type="number"
              step="0.1"
              placeholder="输入层高"
              value={altitudeParams.height}
              onChange={handleAltitudeParamChange}
              className="h-9"
            />
          </div>
          <div className="flex items-center gap-2 flex-1">
            <Label htmlFor="base_height" className="text-sm whitespace-nowrap">
              安全高度 (米)：
            </Label>
            <Input
              id="base_height"
              name="base_height"
              type="number"
              step="0.1"
              placeholder="输入安全高度"
              value={altitudeParams.base_height}
              onChange={handleAltitudeParamChange}
              className="h-9"
            />
          </div>
        </div>

        {/* 高程获取模式选择 */}
        <div className="flex items-center gap-2 flex-1">
          <Label className="text-sm whitespace-nowrap">高程模式：</Label>
          <RadioGroup
            value={altitudeParams.elev_mode}
            onValueChange={(value) => setAltitudeParams((prev) => ({ ...prev, elev_mode: value }))}
            className="flex items-center space-x-8"
          >
            <div className="flex items-center space-x-2">
              <RadioGroupItem value="max" id="elev-mode-max" />
              <Label htmlFor="elev-mode-max">最高点</Label>
            </div>
            <div className="flex items-center space-x-2">
              <RadioGroupItem value="center" id="elev-mode-center" />
              <Label htmlFor="elev-mode-center">中心点</Label>
            </div>
            <div className="flex items-center space-x-2">
              <RadioGroupItem value="min" id="elev-mode-min" />
              <Label htmlFor="elev-mode-min">最低点</Label>
            </div>
          </RadioGroup>
        </div>

        {/* 输出坐标系选择 */}
        <h4 className="font-medium">输出坐标系</h4>
        <div className="flex items-center gap-4">
          <RadioGroup
            value={targetEpsg.toString()}
            onValueChange={(value) => setTargetEpsg(parseInt(value))}
            className="flex items-center space-x-8"
          >
            <div className="flex items-center space-x-2">
              <RadioGroupItem value="3857" id="epsg-3857" />
              <Label htmlFor="epsg-3857">Web墨卡托 (EPSG:3857)</Label>
            </div>
            <div className="flex items-center space-x-2">
              <RadioGroupItem value="4326" id="epsg-4326" />
              <Label htmlFor="epsg-4326">WGS84经纬度 (EPSG:4326)</Label>
            </div>
          </RadioGroup>
        </div>

        {/* 进度指示器 */}
        {renderProgressIndicator}

        <Button
          className="w-full mt-4 "
          disabled={!geojsonPath || !tifPath || !outputDir || isLoading}
          onClick={handleGenerateSlices}
        >
          {isLoading ? '生成中...' : '生成网格切片'}
        </Button>
      </CardContent>
    </Card>
  )
}

export default ElevationGridSlicer
